import { Component, Host, ViewChild } from "@angular/core";
import { AppComponent } from "../../../app/app.component";
import { WeightMatricesService } from "./weightMatrices.service";
import { ColumnOptions, ColumnType } from "../../shared/components/table/models/columnOptions.model";
import { TableButton, ButtonType } from "../../shared/components/table/models/tableButton.model";
import { LrtmService, LongRunningTaskTypeEnum } from "../../framework/lrtm/lrtm.service";
import * as moment from 'moment';
import { ToasterService } from "angular2-toaster";
import { UtilsService } from "../../shared/services/utils.service";
import swal, { SweetAlertOptions } from "sweetalert2";
import { TableComponent, PaginationPositionDisplayEnum } from "../../shared/components/table/table.component";
import { FileUploader } from "ng2-file-upload";
import { ModalComponent } from "../../shared/components/modal/modal.component";
import { forkJoin } from "rxjs";

@Component({
    templateUrl: "weightMatrices.component.html",
    providers: [WeightMatricesService]
})
export class WeightMatricesComponent {
    public slots: number;
    public accounts: any[];
    public selectedAccount: string;
    public count: number;
    public matrices: any[];
    private scheduled: any[];
    public matrixUploader: FileUploader;
    public matrix: any;
    private file: any;
    private matrixArray: any[];
    private account: any;
    public paginationPosition = PaginationPositionDisplayEnum.Down;
    
    @ViewChild('weightTable') weightTable: TableComponent;
    @ViewChild('matrixModal') matrixModal: ModalComponent;
    @ViewChild('selectedMatrix') selectedMatrix: any;

    public columns: ColumnOptions[] = [
        new ColumnOptions('name', 'Custom Matrix Name', 'col-md-3', false, ColumnType.Label),
        new ColumnOptions('deletion', 'Marked for deletion on', 'col-md-3', false, ColumnType.DateTime),
        new ColumnOptions('selected', 'Selected in active profile', 'col-md-2', false, ColumnType.Label),
        new ColumnOptions('slots', 'X of 5 used slots (Tier 1)', 'col-md-4', false, ColumnType.Buttons)
    ];

    constructor(@Host() private rootComponent: AppComponent,
        private matricesService: WeightMatricesService,
        private lrtmService: LrtmService,
        private toasterService: ToasterService) { }

    ngOnInit() {
        this.matrixUploader = new FileUploader({});
        this.matricesService.getSlots().subscribe(data => {
            this.slots = data;
        });

        this.matricesService.getAccounts().subscribe(data => {
            this.accounts = data;
            this.rootComponent.finishLoading();
        });

        this.matrixUploader.onAfterAddingFile = (data: any) => {
            this.file = data.file;
        };
    }

    public addMatrix() {
        if (this.account.platformTier == 100000002)
            this.toasterService.pop('warning', 'A Tier 3 Type customer cannot upload custom matrices')
        else if (this.slots + 1 >= 100)
            this.toasterService.pop('warning', 'We do not support more than 100 matrices on GAP')
        else if (this.account.platformTier == 100000000 && this.count + this.scheduled.length >= 5)
            this.toasterService.pop('warning', 'Selected account cannot have more than 5 custom weight matrices')
        else if (this.account.platformTier == 100000001 && this.count + this.scheduled.length >= 2)
            this.toasterService.pop('warning', 'Selected account cannot have more than 2 custom weight matrices')
        else {
            this.selectedMatrix.nativeElement.value = "";
            this.matrix = {
                name: ''
            };
            this.matrixModal.show();
        }
    }

    private uploadMatrix(matrixId: string) {
        let params: any =
        {
            accountId: this.selectedAccount,
            name: this.matrix.name
        };

        if (matrixId) params['id'] = matrixId;

        this.lrtmService.runTask(this.rootComponent, 'Upload ' + this.matrix.name + ' weight matrix', LongRunningTaskTypeEnum.WeightMatrixUpload, params, false, [this.file.rawFile])
            .subscribe(taskId => {  
                this.matrixModal.hide();
                this.getMatrices();               
            });
    }

    public getMatrices() {
        this.account = this.accounts.find(x => x.id == this.selectedAccount);
        forkJoin([this.matricesService.getMatrices(this.selectedAccount), this.matricesService.getScheduledMatrices(this.selectedAccount)]).subscribe(data => {            
            this.matrixArray = data[0];
            this.matrices = this.matrixArray.map(matrix => {
                return {
                    name: matrix.name,
                    deletion: matrix.markedForDeletionOn == null ? '' : new Date(matrix.markedForDeletionOn),
                    selected: matrix.isSelectedInActiveProfile,
                    action: [
                        new TableButton('edit', { id: matrix.id, name: matrix.name, operation: 'edit' }, true, ButtonType.Button),
                        new TableButton('delete', { id: matrix.id, name: matrix.name, operation: 'delete' }, true, ButtonType.Button),
                        new TableButton('download', { id: matrix.id, name: matrix.name, operation: 'download' }, true, ButtonType.Button)
                    ]
                }
            });
            this.count = this.matrixArray.length;
            this.scheduled = data[1].filter(x => this.matrices.filter(y=> y.name == x.name).length == 0);
            this.columns[this.columns.length - 1].name = this.count + (this.account.platformTier == 100000000 ? ' of 5 used slots (Tier 1)' : ' of 2 used slots (Tier 2)') +
                (this.scheduled.length > 0 ? ' with ' + this.scheduled.length + ' new scheduled matrices' : '')
            this.weightTable.updateColumns(this.columns);
        });
    }

    public onButtonClicked(event: any) {
        switch (event.operation) {
            case 'edit':
                this.matrix = this.matrixArray.find(x => x.id == event.id);
                this.selectedMatrix.nativeElement.value = "";
                this.matrixModal.show();
                break;
            case 'delete':
                const swalOptions: SweetAlertOptions = Object.assign(UtilsService.getBaseSwalOptions(), {
                    title: 'Delete Matrix',
                    text: 'Are you sure you want to delete this weight matrix?',
                    confirmButtonClass: 'btn btn-primary',
                    confirmButtonText: "Yes, I'm sure",
                    imageUrl: '/assets/icons-svg/icon-warning.svg'
                });

                swal(swalOptions).then(result => {
                    if (result && result.value) {
                        this.matricesService.removeMatrix(event.id).subscribe(
                            data => {
                                let index = this.matrices.findIndex(x => x.id == event.id);
                                this.matrices.splice(index, 1);
                                this.weightTable.updateSource(this.matrices);
                            },
                            error => { this.toasterService.pop('error', 'Error removing custom weight matrix') });
                    }
                });
                break;
            case 'download':
                //download operation
                this.lrtmService.runTask(this.rootComponent, event.name + "_" + moment().format("YYYY-MM-DD_HH-mm-ss-SSS"),
                    LongRunningTaskTypeEnum.WeightMatrixDownload, { weightMatrixId: event.id }, true).subscribe(_ => { });
                break;
        }
    }

    public saveMatrix() {
        this.uploadMatrix(this.matrix.id);
    }
}